import React, { useEffect, useState } from 'react';
import { Box, DropdownMenu as Dropdown, makeToast, Modal, Text } from '@nova-hf/ui';
import { AlltSamanBar } from 'beta/containers/allt-saman-bar/AlltSamanBar';
import ContractWrapper from 'beta/containers/layout/ContractWrapper';
import { PaymentHistory } from 'beta/containers/payment-history/PaymentHistory';
import { PaymentOptions } from 'beta/containers/payment-history/PaymentOptions';
import { PaymentPostponement } from 'beta/containers/payment-history/PaymentPostponement';
import { IContext } from 'beta/typings/context';
import { useRouter } from 'next/router';
import {
  InvoiceType,
  SubscriptionPeriodStatus,
  useContractInvoicesQuery,
  usePayInvoiceMutation,
  usePostponeInvoiceMutation,
} from 'typings/graphql';
import { useTranslation } from 'utils/i18n';

const COLOR = 'orange';
const perPage = 10;

const GreidsluSaga = () => {
  const { t } = useTranslation(['subscription', 'alltSaman']);
  const allOrders = [
    t('paymentHistory.orders.one'),
    t('paymentHistory.orders.two'),
    t('paymentHistory.orders.three'),
    t('paymentHistory.orders.four'),
  ];
  const router = useRouter();
  const contractId = router.query.contractId ?? '';
  const customerId = router.query.customerId ?? '';
  const [page, setPage] = useState(1);
  const [sort, setSort] = useState('PeriodEnd');
  const [direction, setDirection] = useState('Descending');
  const [filterText, setFilterText] = useState(t('paymentHistory.order').toString());
  const [paidText, setPaidText] = useState('Allt');
  const [type, setType] = useState(undefined);
  const [isPaid, setIsPaid] = useState(undefined);
  const [typeText, setTypeText] = useState(t('paymentHistory.type').toString());
  const [paymentModal, setPaymentModal] = useState(false);
  const [postponeModal, setPostponeModal] = useState(false);
  const { data, refetch, loading } = useContractInvoicesQuery({
    variables: {
      input: {
        contractId: contractId.toString(),
        page: page,
        perPage: perPage,
        type: type ?? undefined,
        sort: sort,
        direction: direction,
        isPaid: isPaid ?? undefined,
      },
    },
  });

  const [payInvoiceMutation] = usePayInvoiceMutation({
    onCompleted() {
      refetch();
    },
    awaitRefetchQueries: true,
  });

  const [postponeInvoiceMutation] = usePostponeInvoiceMutation({
    onCompleted() {
      refetch();
    },
    awaitRefetchQueries: true,
  });

  const invoices = data?.contractsInvoices?.invoices;
  const unpaidInvoices = invoices?.filter(
    (invoice) => invoice?.status !== SubscriptionPeriodStatus.Paid,
  );
  const newestUnpaidInvoice = unpaidInvoices ? unpaidInvoices[0] : undefined;
  const total = data?.contractsInvoices?.pageInfo?.totalCount;
  const reArange = (newSort: string, newDirection: string) => {
    setSort(newSort);
    setDirection(newDirection);
  };

  const filter = (newType: InvoiceType | undefined) => {
    setType(newType);
  };

  const paidOrUnpaid = (status: boolean | undefined) => {
    setIsPaid(status);
  };

  const goBack = () => {
    setPaymentModal(false);
    setPostponeModal(false);
  };

  const postponeFunction = () => {
    setPostponeModal(true);
  };

  const onPayClick = async (id: string) => {
    try {
      if (id) {
        const { data: payInvoiceData } = await payInvoiceMutation({
          variables: {
            input: {
              id: id,
            },
          },
        });
        if (payInvoiceData) {
          makeToast.success(t('alltSaman:alltSaman.paymentSuccess'), '');
        }
      }
    } catch (error) {
      if (error instanceof Error) {
        makeToast.danger(t('alltSaman:alltSaman.paymentFailed'), error.message);
        setPaymentModal(true);
      }
    }
  };

  const onPostponeClick = async () => {
    try {
      if (newestUnpaidInvoice?.id) {
        const { data: postponeInvoiceData } = await postponeInvoiceMutation({
          variables: {
            input: {
              id: newestUnpaidInvoice.id,
            },
          },
        });
        if (postponeInvoiceData) {
          makeToast.success(t('alltSaman:alltSaman.postponeSuccess'), '');
          setPostponeModal(false);
        }
      }
    } catch (error) {
      if (error instanceof Error) {
        makeToast.danger(t('alltSaman:alltSaman.postponeSuccess'), error.message);
        setPostponeModal(false);
      }
    }
  };

  useEffect(() => {
    refetch();
  }, [type, sort, isPaid, direction, refetch]);

  return (
    <ContractWrapper>
      <Box>
        <Modal
          ariaLabel="paymentOptions"
          onVisibilityChange={(isVisible) => setPaymentModal(isVisible)}
          isVisible={paymentModal}
        >
          <PaymentOptions color={COLOR} postpone={postponeFunction} />
        </Modal>
        <Modal
          ariaLabel="postponePayment"
          onVisibilityChange={(isVisible) => setPostponeModal(isVisible)}
          isVisible={postponeModal}
        >
          <PaymentPostponement
            color={COLOR}
            cancel={goBack}
            postponeDate={newestUnpaidInvoice?.periodEnd ? newestUnpaidInvoice.periodEnd : ''}
            postpone={onPostponeClick}
          />
        </Modal>
        <Box
          marginBottom={5}
          display="flex"
          justifyContent="space-between"
          alignItems="center"
          flexDirection="row"
        >
          <Text variant="h6">{t('subscription:paymentHistory.history')}</Text>
          <Box display="flex" alignItems="center" gap={2} flexDirection="row">
            <Dropdown
              buttonText={filterText}
              color={'orange'}
              items={[
                {
                  onClick: () => {
                    reArange('PeriodEnd', 'Descending');
                    setFilterText(allOrders[0]);
                  },
                  text: allOrders[0],
                  isActive: filterText === allOrders[0] ?? false,
                },
                {
                  onClick: () => {
                    reArange('PeriodEnd', 'Ascending');
                    setFilterText(allOrders[1]);
                  },
                  text: allOrders[1],
                  isActive: filterText === allOrders[1] ?? false,
                },
                {
                  onClick: () => {
                    reArange('Amount', 'Descending');
                    setFilterText(allOrders[2]);
                  },
                  text: allOrders[2],
                  isActive: filterText === allOrders[2] ?? false,
                },
                {
                  onClick: () => {
                    reArange('Amount', 'Ascending');
                    setFilterText(allOrders[3]);
                  },
                  text: allOrders[3],
                  isActive: filterText === allOrders[3] ?? false,
                },
              ]}
            />
            <Dropdown
              buttonText={typeText}
              color={COLOR}
              items={[
                {
                  onClick: () => {
                    filter(InvoiceType.SubscriptionCharge);
                    setTypeText(t('alltSaman:alltSaman.monthly'));
                  },
                  text: t('alltSaman:alltSaman.monthly'),
                  isActive: typeText === t('alltSaman:alltSaman.monthly') ?? false,
                },
                {
                  onClick: () => {
                    filter(InvoiceType.UsageCharge);
                    setTypeText(t('alltSaman:alltSaman.extraCost'));
                  },
                  text: t('alltSaman:alltSaman.extraCost'),
                  isActive: typeText === t('alltSaman:alltSaman.extraCost') ?? false,
                },
                {
                  onClick: () => {
                    filter(undefined);
                    setTypeText(t('alltSaman:alltSaman.all'));
                  },
                  text: t('alltSaman:alltSaman.all'),
                  isActive: typeText === t('alltSaman:alltSaman.all') ?? false,
                },
              ]}
            />
            <Dropdown
              buttonText={paidText}
              color={COLOR}
              items={[
                {
                  onClick: () => {
                    paidOrUnpaid(true);
                    setPaidText(t('alltSaman:alltSaman.paid'));
                  },
                  text: t('alltSaman:alltSaman.paid'),
                  isActive: isPaid === true,
                },
                {
                  onClick: () => {
                    paidOrUnpaid(false);
                    setPaidText(t('alltSaman:alltSaman.other'));
                  },
                  text: t('alltSaman:alltSaman.other'),
                  isActive: isPaid === false,
                },
                {
                  onClick: () => {
                    paidOrUnpaid(undefined);
                    setPaidText(t('alltSaman:alltSaman.all'));
                  },
                  text: t('alltSaman:alltSaman.all'),
                  isActive: isPaid === undefined,
                },
              ]}
            />
          </Box>
        </Box>
        {newestUnpaidInvoice && (
          <Box marginBottom={8}>
            <AlltSamanBar
              isLoading={loading}
              color={COLOR}
              invoice={newestUnpaidInvoice}
              onButtonClick={onPayClick}
              onPostpone={postponeFunction}
            />
          </Box>
        )}
        {invoices && invoices?.length > 0 && (
          <PaymentHistory
            invoices={invoices}
            customerId={customerId.toString()}
            color={COLOR}
            perPage={perPage}
            page={page}
            total={total}
            setPage={setPage}
            onPay={onPayClick}
          />
        )}
      </Box>
    </ContractWrapper>
  );
};

GreidsluSaga.getInitialProps = ({ pathname, query }: IContext) => {
  return {
    pathname,
    serviceId: query.serviceId,
    namespacesRequired: ['subscription', 'alltSaman'],
  };
};

export default GreidsluSaga;
